package com.moodincode.taskcenter.bean;

import com.moodincode.taskcenter.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.lang.reflect.Method;

/**
 * 任务代理类，如果实现类不实现job,则需要调用其指定的方法进行代理
 * @author moodincode
 */
@Slf4j
public class JobProxy implements Job {
    /**
     * 执行的类对应的bean实例,全路径，例如com.moodincode.taskcenter.XX
     */
    public static final String DATA_JOB_BEAN_CLASS_NAME="DATA_BEAN_CLASS_NAME";
    /**
     * 执行的方法名，Method method
     */
    public static final String DATA_JOB_METHOD_NAME="DATA_JOB_METHOD_NAME";
    /**
     * 执行方法的入参 Object[] params
     */
    public static final String DATA_JOB_METHOD_PARAMS="DATA_JOB_METHOD_PARAMS";
    private Object bean=null;
    private Method method=null;
    private Object[] params=null;
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        if(bean==null){
            //初始化bean
            initBeanAndMethod(context);
        }
        if(bean==null||method==null){
            log.error("定时任务配置参数有误");
            throw new JobExecutionException("定时任务配置参数有误");
        }
        try {
            //执行代理任务
            method.invoke(bean,params);
        } catch (Exception e) {
           log.error("代理执行定时任务异常",e);
        }
    }

    /**
     * 手动注入bean对象
     * @param context
     */
    private void initBeanAndMethod(JobExecutionContext context) {
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String beanClassName=(String)dataMap.get(DATA_JOB_BEAN_CLASS_NAME);
        String methodName= (String) dataMap.get(DATA_JOB_METHOD_NAME);
        if(null==beanClassName||null==methodName){
            return;
        }
        try {
            Class<?> cls = Class.forName(beanClassName);
            if(cls==null){
                log.error("定时任务bean不存在，beanClassName={}",beanClassName);
                return;
            }
             bean = SpringContextUtil.getBean(cls);
            if(bean==null){
                String[] split = beanClassName.split("\\.");
                String beanName=split[split.length-1];
                String lowerBeanName = Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1);
                bean= SpringContextUtil.registerBean(lowerBeanName,cls) ;
            }
            method=cls.getMethod(methodName);
            params= (Object[]) dataMap.get(DATA_JOB_METHOD_PARAMS);
        } catch (ClassNotFoundException |InstantiationException|IllegalAccessException|NoSuchMethodException e) {
           log.error("获取定时任务执行对象方法异常，class={},method={}",beanClassName,methodName,e);
        }
    }
}
